using Godot;
using Godot.Collections;
using System;


public partial class DialogueConfig : Area2D
{

	[ExportGroup("Positioning")]
	[Export]
	public Node2D PopTipPosition { get; set; }
	[Export]
	public Node2D CameraFocusPosition { get; set; }
	[Export]
	public float CameraZoom { get; set; } = -1.0f;
	[Export]
	public Vector2 CameraOffset { get; set; } = Vector2.Zero;
	private Vector2 _originalOffset;

	[ExportGroup("Contents")]
	[Export]
	public Array<string> Sentences { get; set; } = [];
	[Export]
	public string TipName { get; set; } = "Interact";

	[ExportGroup("Callback event")]
	[Export]
	public string CallbackEvent { get; set; } = "";
	[Export]
	public Dictionary<string, Variant> CallbackEventArgs { get; set; } = [];

	// Get NodeMap
	private GamePlayGui _bindGUI;
	private Player _player;
	private CinematicCamera _camera;

	// Signs
	private bool _activated = false;

	// Called when the node enters the scene tree for the first time.
	public override void _Ready()
	{
		var map = GetNode<NodeReferenceMap>(Constants.NodeRefMapPath);

        _bindGUI = map.MainGui;
		_bindGUI.InteractionPressed += Signal_InteractionPressed;
		_bindGUI.DialogueBoxFinished += Signal_DialogueFinished;

		_player = map.MainPlayer;
		_camera = map.GameCamera;
	}

    public override void _ExitTree()
    {
        _bindGUI.InteractionPressed -= Signal_InteractionPressed;
        _bindGUI.DialogueBoxFinished -= Signal_DialogueFinished;
    }

	// Export interfaces
	public void PrepareDialogue()
	{
		_activated = true;
		_bindGUI.SetFloatingAnchor(PopTipPosition);
		_bindGUI.ShowInteractionTips(TipName);
	}

	public void CancelDialogue()
	{
		_activated = false;
		_bindGUI.ResetFloatingAnchor();
		_bindGUI.HideInteractionTips();
	}

	// GODOT Signals
	private void Signal_InteractionPressed()
	{
		if (_activated)
		{
			bool setFocus = CameraFocusPosition != null, setZoom = CameraZoom > 0.0f;
			_camera.PushCameraAreaConfig(
				setFocus, setZoom, false, false, CameraFocusPosition, CameraZoom
			);
			if (CameraOffset != Vector2.Zero)
			{
				_originalOffset = _camera.FocusOffset;
				_camera.FocusOffset = CameraOffset;
			}
			
			_bindGUI.HideInteractionTips();
			_bindGUI.ResetFloatingAnchor();
			_bindGUI.ChangeDialogueContent(Sentences);
			_bindGUI.OpenDialogueBox();
			_player.SkipInputCheck();
        }
	}

	private void Signal_DialogueFinished()
	{
		if (_activated)
		{
            if (CameraOffset != Vector2.Zero)
				_camera.FocusOffset = _originalOffset;
			_camera.PopCameraAreaConfig();
            _player.EnableInputCheck();
			_player.HandleCustomEvent(CallbackEvent, CallbackEventArgs);
			_activated = false;
		}
	}
}
